/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
 *
 */

import { spawnSync } from 'child_process';
import * as fs from 'fs';
import os from 'os';
import * as path from 'path';

import { DEFAULT_PACKAGE_JSON, PNPM, PNPM_TOOL } from '../common/const/const.js';
import { PackageJson } from '../common/type.js';
import { getHvigorUserHomeCacheDir } from '../common/util/hvigor-user-home.js';

import { readProjectHvigorConfig } from './hvigor-installer.js';
import { logFormatedError, logFormatedErrorAndExit, logInfo } from './log.js';
import { executeCommand, getNpmPath, hasNpmPackInPaths, isFileExists } from './util.js';

export const PNPM_VERSION = '8.13.1';

/**
 * 检查npmrc是否配置
 *
 */
export function checkNpmConifg() {
  const projectNpmrcPath = path.resolve(process.cwd(), '.npmrc');
  const userNpmrcPath = path.resolve(os.homedir(), '.npmrc');

  if (process.env['npm_config_registry'] && process.env['npm_config_@ohos:registry']) {
    return;
  }

  const hvigorConfigJson = readProjectHvigorConfig();
  if (!hvigorConfigJson?.dependencies || Object.entries(hvigorConfigJson?.dependencies).length === 0) {
    return;
  }

  if (isFileExists(projectNpmrcPath) || isFileExists(userNpmrcPath)) {
    return;
  }

  // 获取全局配置
  const npmPath = getNpmPath();
  const command = ['config', 'get', 'prefix'];
  const executeResult = spawnSync(npmPath, command, {
    cwd: process.cwd(),
  });

  if (executeResult.status !== 0 || !executeResult.stdout) {
    notExistNpmrcLog();
    return;
  }

  const globalNpmrcPath = path.resolve(`${executeResult.stdout}`.replace(/[\r\n]/gi, ''), '.npmrc');
  if (isFileExists(globalNpmrcPath)) {
    return;
  }
  notExistNpmrcLog();
}

function notExistNpmrcLog() {
  logFormatedError('00303137', 'The hvigor depends on the npmrc file. No npmrc file is matched in the current user folder. Configure the npmrc file first.',
    ['Configure the .npmrc file in the user directory.']);
}

/**
 * 处理环境变量
 */
export function environmentHandler() {
  process.env['npm_config_update-notifier'] = 'false';
  process.env['npm_config_auto-install-peers'] = 'false';
}

const HVIGOR_USER_HOME = getHvigorUserHomeCacheDir();
const HVIGOR_WRAPPER_TOOLS_HOME = path.resolve(HVIGOR_USER_HOME, 'wrapper', 'tools');
const HVIGOR_WRAPPER_PNPM_SCRIPT_PATH = path.resolve(HVIGOR_WRAPPER_TOOLS_HOME, 'node_modules', '.bin', PNPM_TOOL);

/**
 * 验证USER_HOME/.hvigor/wrapper/tools目录下pnpm是否可用
 *
 * @returns {boolean} true/false
 */
export function isPnpmInstalled(): boolean {
  if (!fs.existsSync(HVIGOR_WRAPPER_PNPM_SCRIPT_PATH)) {
    return false;
  }

  return hasNpmPackInPaths('pnpm', [HVIGOR_WRAPPER_TOOLS_HOME]);
}

/**
 * 生成一个默认的空package.json
 * 由于低版本的nodejs中执行npm install时,要求必须有一个package.json
 */
function pnpmPackageJsonExists() {
  const defaultPackageJsonPath = path.resolve(HVIGOR_WRAPPER_TOOLS_HOME, DEFAULT_PACKAGE_JSON);
  try {
    if (!fs.existsSync(HVIGOR_WRAPPER_TOOLS_HOME)) {
      fs.mkdirSync(HVIGOR_WRAPPER_TOOLS_HOME, { recursive: true });
    }

    const emptyPackageJson: PackageJson = {
      dependencies: {},
    };
    emptyPackageJson.dependencies[PNPM] = PNPM_VERSION;

    fs.writeFileSync(defaultPackageJsonPath, JSON.stringify(emptyPackageJson));
  } catch (e) {
    logFormatedErrorAndExit('00307001', `EPERM: operation not permitted,create ${defaultPackageJsonPath} failed.`,
      ['Check whether you have the permission to write files.']);
  }
}

/**
 * 执行pnpm的安装
 */
export function executeInstallPnpm() {
  logInfo(`Installing pnpm@${PNPM_VERSION}...`);
  const npmPath = getNpmPath();

  const commandParams = ['install', 'pnpm'];

  // 低版本的npm,必须存在一个符合规范的package.json再执行install才会生效
  pnpmPackageJsonExists();
  executeCommand(npmPath, commandParams, {
    cwd: HVIGOR_WRAPPER_TOOLS_HOME,
    stdio: ['inherit', 'inherit', 'inherit'],
    env: process.env,
  });
  logInfo('Pnpm install success.');
}
